home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 3d_lib.zip / AC.C < prev    next >
C/C++ Source or Header  |  1993-05-09  |  5KB  |  140 lines

  1. /* Add corner to face
  2.  
  3.    Copyright (c) 1988 by Gus O'Donnell
  4.  
  5.    Revision history:
  6.  
  7.    Version 1.00         February 29, 1988       As released.
  8.  
  9.    Version 1.01         March 20, 1988          Created libraries for all
  10.                                                 memory models
  11.  
  12. */
  13. #include "3d.h"
  14. #include <alloc.h>
  15. #include <float.h>
  16. #include <math.h>
  17. #include <stdio.h>
  18.  
  19. int     add_corner (double x, double y, double z, FACE *this_face)
  20.  
  21. /* Add a corner to a face.  The initial data structure looks like this:
  22.  
  23.  
  24.                FACE X o----->CORNER o X
  25.                                     |
  26.                                 +---+
  27.                                 |
  28.                                 V
  29.                              CORNER X X
  30.  
  31.  
  32. Where 'X' is the NULL pointer.  The revised structure looks like this:
  33.  
  34.  
  35.                FACE X o----->CORNER o X
  36.                                     |
  37.                                 +---+
  38.                                 |
  39.                                 V
  40.                              CORNER X o----->VERTEX X
  41.                                     |
  42.                                 +---+
  43.                                 |
  44.                                 V
  45.                              CORNER X X
  46.  
  47.  
  48. Note that the corner is added to the beginning of the list.  The corners
  49. are assumed to be added in "standard" order, that is, counterclockwise
  50. as the face is viewed from the outside of the object.
  51.  
  52. The new corner is checked for colinearity with the first two corners.
  53. If it is colinear, it replaces the current first corner.  The test
  54. proceeds as follows:
  55.  
  56. Calculate the parametric representation of the line formed by the
  57. first two corners:
  58.  
  59.                         X = A + t(B - A)                   (1)
  60.  
  61. where X is any point on the line, A and B are two points on the line
  62. (the first two corners of the face), and t is the parameter.  Thus:
  63.  
  64.                         X[0] = A[0] + t(B[0] - A[0]),
  65.                         X[1] = A[1] + t(B[1] - A[1]),
  66.                         X[2] = A[2] + t(B[2] - A[2]),      (2)
  67.  
  68. Substitute the new corner's coordinates into the parametric equations
  69. and calculate t for any dimension i such that A[i] != B[i]:
  70.  
  71.                     t = (C[i] - A[i])/(B[i] - A[i])        (3)
  72.  
  73. If all equations (2) are satisfied with this value of t, the points are
  74. colinear.
  75.  
  76. The value returned is the status:
  77.  
  78.                    0 - success.
  79.                    1 - memory allocation failed.
  80.                    2 - corner is colinear, replaced first
  81.                        corner with new corner.
  82.  
  83. */
  84.  
  85. {
  86.     int count;
  87.     CORNER *chandle;    /* Handle for new corner */
  88.     VERTEX *vhandle;    /* Handle for new vertex */
  89.     VECTOR A,B,X;       /* Temporary storage for colinearity check */
  90.     double t;           /* Line parameter */
  91.  
  92.     /* Test for colinearity */
  93.  
  94.     chandle = this_face -> first -> next;
  95.     if ((chandle -> next) != NULL)                      /* At least 1 corner */
  96.     {
  97.         for (count = 0; count < DIM; count++)
  98.             A [count] = chandle -> this -> coord [count];  /* Get 1st corner */
  99.         chandle = chandle -> next;
  100.         if ((chandle -> next) != NULL)                 /* Face has 2 corners */
  101.         {
  102.             t = 0.0;
  103.             X[0] = x;
  104.             X[1] = y;
  105.             X[2] = z;
  106.             for (count = 0; count < DIM; count++)
  107.             {
  108.                 B [count] = chandle -> this -> coord [count];  /* 2nd corner */
  109.                 if (A[count] != B[count])
  110.                     t = (X[count] - A[count])/(B[count] - A[count]);
  111.                     count = DIM;                              /* Out of loop */
  112.             }
  113.             if   ((X[0] == A[0] + t*(B[0] - A[0]))
  114.                && (X[1] == A[1] + t*(B[1] - A[1]))
  115.                && (X[2] == A[2] + t*(B[2] - A[2])))     /* Point is colinear */
  116.             {
  117.                 chandle = this_face -> first -> next;
  118.                 for (count = 0; count < DIM; count++)
  119.                                                    /* Assign new coordinates */
  120.                                                    /* to existing 1st corner */
  121.                     chandle -> this -> coord [count] = X[count];
  122.                 return (2);                             /* and return status */
  123.             }
  124.         }
  125.     }
  126.  
  127.     /* If point is not colinear, get memory.  Return a 1 if unsuccessful. */
  128.  
  129.     if (!(chandle = (CORNER *)malloc(sizeof(CORNER)))) return(1);
  130.     if (!(vhandle = (VERTEX *)malloc(sizeof(VERTEX)))) return(1);
  131.     chandle -> next = this_face -> first -> next;
  132.     this_face -> first -> next = chandle;
  133.     chandle -> this = vhandle;
  134.     vhandle -> coord [0] = x;
  135.     vhandle -> coord [1] = y;
  136.     vhandle -> coord [2] = z;
  137.     vhandle -> next = NULL;
  138.     return(0);
  139. }
  140.